﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TinyMoocSite.DataAccessLayer;
using TinyMoocSite.Models;
using TinyMoocSite.ViewModels;
using System.IO;

namespace TinyMoocSite.Helpers
{
    public class CourseInfoHelper
    {
        public CourseList GetCourseList(string loginUser = null)
        {
            CourseList courseList = new CourseList();
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList = dal.CourseInfo.Include("FollowedUserList").ToList();
            courseList.CourseItems = new List<CourseShortItem>();

            foreach (CourseInfo course in courseInfoList)
            {
                CourseShortItem shortItem = new CourseShortItem();
                shortItem.CourseId = course.Id.ToString();
                shortItem.CourseTitle = course.Title;
                shortItem.Description = course.Description;
                shortItem.StartTime = course.StartDate.ToLongDateString();
                shortItem.EndTime = course.EndDate.ToLongDateString();
                if (loginUser != null)
                    shortItem.Picked =
                        (course.FollowedUserList.Where(p => p.Username == loginUser).Count() == 1);

                List<UserInfo> teachers = 
                    course.FollowedUserList.Where(p => p.Privilege == UserPrivilege.Teacher).ToList();
                var a = from p in teachers select p.FullName;
                shortItem.Teachers = string.Join(", ", a);
                courseList.CourseItems.Add(shortItem);
            }

            return courseList;
        }

        public void UpdateCoursePartialOverview(UpdateOverviewForm form)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id == form.Id).ToList();

            if (courseInfoList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];
            switch (form.SectionName)
            {
                case "Description":
                    course.Description = form.Content;
                    break;
                case "Prerequisites":
                    course.Prerequisites = form.Content;
                    break;
                case "Textbook":
                    course.Textbook = form.Content;
                    break;
                case "ScoringRule":
                    course.ScoringRule = form.Content;
                    break;
            }

            dal.SaveChanges();
        }

        public HomeworkVM GetHomeworkData(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];

            HomeworkVM vm = new HomeworkVM();
            vm.HomeworkList = new List<HomeworkShortItem>();
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            foreach (Homework homework in course.HomeworkList)
            {
                HomeworkShortItem item = new HomeworkShortItem();
                item.Id = homework.Id.ToString();
                item.Title = homework.Title;
                item.StartDate = homework.StartDate.ToString();
                item.EndDate = homework.EndDate.ToString();
                item.Owner = homework.Owner.FullName;
                item.CompletedCount = 
                    dal.HomeworkHistory.Include("ChosenHomework").Where(p => p.ChosenHomework.Id == homework.Id).Count().ToString();
                vm.HomeworkList.Add(item);
            }

            return vm;
        }

        public DiscussVM GetDiscussShortItemArray(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList").Include("DiscussList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            DiscussVM vm = new DiscussVM();
            vm.DiscussList = new List<DiscussShortItem>();
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();
            foreach (Discuss discuss in course.DiscussList)
            {
                DiscussShortItem item = new DiscussShortItem();
                item.Id = discuss.Id.ToString();
                item.PostTitle = discuss.PostTitle;
                item.PostDate = discuss.PostDate.ToString();
                item.Owner = discuss.Owner.FullName;
                item.ReplyCount = discuss.ReplyList.Count().ToString();
                vm.DiscussList.Add(item);
            }

            return vm;
        }

        public DiscussContentVM GetDiscussContent(string courseId, string discussId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList.Owner").Include("DiscussList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            List<Discuss> discussList =
                dal.Discuss.Include("ReplyList.Owner").Include("Owner").Where(p => p.Id.ToString() == discussId).ToList();
            if (discussList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            Discuss discuss = discussList[0];
            DiscussContentVM vm = new DiscussContentVM();

            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            vm.PostId = discussId;
            vm.PostTitle = discuss.PostTitle;
            vm.PostDate = discuss.PostDate.ToString();
            vm.Content = discuss.Content;
            vm.Owner = discuss.Owner.FullName;
            vm.Replies = new List<DiscussReplyVM>();

            foreach (DiscussReply item in discuss.ReplyList)
            {
                vm.Replies.Add(new DiscussReplyVM
                {
                    Id = item.Id.ToString(),
                    Owner = item.Owner.FullName,
                    PostDate = item.PostDate.ToString(),
                    Content = item.Content
                });
            }

            return vm;
        }

        public void RegisterCourse(string courseId, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<UserInfo> userInfoList = dal.UserInfo.Where(p => p.Username == userName).ToList();
            if (userInfoList.Count != 1)
                return;
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return;

            courseInfoList[0].FollowedUserList.Add(userInfoList[0]);
            dal.SaveChanges();
        }

        public void CompleteHomework(HomeworkFullItem form, string answerArray, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<Homework> homeworkList =
                dal.Homework.Where(p => p.Id.ToString() == form.HomeworkId).ToList();
            if (homeworkList.Count != 1)
                return;            
            
            List<UserInfo> userInfoList = dal.UserInfo.Where(p => p.Username == userName).ToList();
            if (userInfoList.Count != 1)
                return;

            HomeworkHistory entry = new HomeworkHistory();
            entry.ChosenHomework = homeworkList[0];
            entry.Applicant = userInfoList[0];
            entry.AnswerArray = answerArray;
            entry.CompletedDate = DateTime.Now;

            dal.HomeworkHistory.Add(entry);
            dal.SaveChanges();
        }

        public void RemoveDiscuss(string discussId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<Discuss> discussList =
                dal.Discuss.Include("ReplyList").Where(p => p.Id.ToString() == discussId).ToList();
            if (discussList.Count != 1)
                return;

            Discuss discuss = discussList[0];
            List<DiscussReply> discussReplyList =
                dal.DiscussReply.Include("Root").Where(p => p.Root.Id == discuss.Id).ToList();
            dal.DiscussReply.RemoveRange(discussReplyList);
            discuss.ReplyList.Clear();
            dal.Discuss.Remove(discuss);
            dal.SaveChanges();
        }

        public void RemoveDiscussReply(string replyId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<DiscussReply> discussReplyList = 
                dal.DiscussReply.Include("Root").Where(p => p.Id.ToString() == replyId).ToList();
            if (discussReplyList.Count != 1)
                return;

            Discuss discuss = discussReplyList[0].Root;
            discuss.ReplyList.Remove(discussReplyList[0]);
            dal.DiscussReply.Remove(discussReplyList[0]);

            dal.SaveChanges();
        }

        public ReplyDiscussForm InitReplyDiscussForm(string courseId, string discussId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList").Include("DiscussList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            List<Discuss> discussList =
                dal.Discuss.Include("ReplyList.Owner").Include("Owner").Where(p => p.Id.ToString() == discussId).ToList();
            if (discussList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            Discuss discuss = discussList[0];
            ReplyDiscussForm vm = new ReplyDiscussForm();

            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();
            vm.PostId = discussId;
            vm.PostTitle = discuss.PostTitle;
            return vm;
        }

        public void ReplyDiscuss(ReplyDiscussForm form, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList").Include("DiscussList.Owner").Where(p => p.Id == form.Id).ToList();
            if (courseInfoList.Count != 1)
                return;

            List<Discuss> discussList =
                dal.Discuss.Include("ReplyList.Owner").Include("Owner").Where(p => p.Id.ToString() == form.PostId).ToList();
            if (discussList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];
            Discuss discuss = discussList[0];

            discuss.ReplyList.Add(new DiscussReply
            {
                Root = discuss,
                PostDate = DateTime.Now,
                Content = form.Content,
                Owner = dal.UserInfo.Where(p => p.Username == userName).ToList()[0]
            });

            dal.SaveChanges();
        }

        public void AddDiscuss(AddDiscussForm form, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList").Include("DiscussList.Owner").Where(p => p.Id == form.Id).ToList();
            if (courseInfoList.Count != 1)
                return;

            Discuss newDiscuss = new Discuss();
            newDiscuss.PostTitle = form.PostTitle;
            newDiscuss.Content = form.Content;
            newDiscuss.PostDate = DateTime.Now;
            newDiscuss.Course = courseInfoList[0];
            newDiscuss.ReplyList = new List<DiscussReply>();
            newDiscuss.Owner = dal.UserInfo.Where(p => p.Username == userName).ToList()[0];
            courseInfoList[0].DiscussList.Add(newDiscuss);

            dal.SaveChanges();
        }

        public HomeworkFullItem GetHomeworkFullItem(string courseId, string homeworkId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Include("HomeworkList.Entries").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            List<Homework> homeworkList =
                dal.Homework.Include("Entries").Include("Owner").Where(p => p.Id.ToString() == homeworkId).ToList();
            if (homeworkList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            Homework homework = homeworkList[0];
            HomeworkFullItem vm = new HomeworkFullItem();

            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            vm.HomeworkId = homework.Id.ToString();
            vm.HomeworkTitle = homework.Title;
            vm.HomeworkStartDate = homework.StartDate.ToLongDateString();
            vm.HomeworkEndDate = homework.EndDate.ToLongDateString();
            vm.Owner = homework.Owner.FullName;
            vm.CompletedCount = 
                 dal.HomeworkHistory.Include("ChosenHomework").Where(p => p.ChosenHomework.Id == homework.Id).Count();

            vm.Problems = new List<ProblemData>();

            foreach (HomeworkEntry item in homework.Entries)
            {
                vm.Problems.Add(new ProblemData
                {
                    Id = item.Id.ToString(),
                    Body = item.Body,
                    CandidateFirst = item.CandidateFirst,
                    CandidateSecond = item.CandidateSecond,
                    CandidateThird = item.CandidateThird,
                    CandidateFourth = item.CandidateFourth,
                    CorrectAnswer = item.CorrectAnswer
                });
            }

            return vm;
        }


        public HomeworkFullItem GetHomeworkFullItemWithMyAnswer(string courseId, string homeworkId, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Include("HomeworkList.Entries").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            List<Homework> homeworkList =
                dal.Homework.Include("Entries").Include("Owner").Where(p => p.Id.ToString() == homeworkId).ToList();
            if (homeworkList.Count != 1)
                return null;

            List<HomeworkHistory> homeworkHistoryList =
                dal.HomeworkHistory.Include("Applicant").Include("ChosenHomework").Where(
                    p => p.Applicant.Username == userName && p.ChosenHomework.Id.ToString() == homeworkId
                ).ToList();

            if (homeworkHistoryList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            Homework homework = homeworkList[0];
            string[] answerArray = homeworkHistoryList[0].AnswerArray.Split(',');

            HomeworkFullItem vm = new HomeworkFullItem();

            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            vm.HomeworkId = homework.Id.ToString();
            vm.HomeworkTitle = homework.Title;
            vm.HomeworkStartDate = homework.StartDate.ToLongDateString();
            vm.HomeworkEndDate = homework.EndDate.ToLongDateString();
            vm.Owner = homework.Owner.FullName;
            vm.Problems = new List<ProblemData>();

            int i = 0;
            foreach (HomeworkEntry item in homework.Entries)
            {
                vm.Problems.Add(new ProblemData
                {
                    Id = item.Id.ToString(),
                    Body = item.Body,
                    CandidateFirst = item.CandidateFirst,
                    CandidateSecond = item.CandidateSecond,
                    CandidateThird = item.CandidateThird,
                    CandidateFourth = item.CandidateFourth,
                    CorrectAnswer = item.CorrectAnswer,
                    MyAnswer = answerArray[i++]
                });
            }

            return vm;
        }

        public void UpdateProblem(UpdateProblemForm form)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<HomeworkEntry> homeworkEntry = 
                dal.HomeworkEntry.Where(p => p.Id.ToString() == form.ProblemId).ToList();
            if (homeworkEntry.Count != 1)
                return;

            HomeworkEntry entry = homeworkEntry[0];
            entry.Body = form.Body;
            entry.CandidateFirst = form.CandidateFirst;
            entry.CandidateSecond = form.CandidateSecond;
            entry.CandidateThird = form.CandidateThird;
            entry.CandidateFourth = form.CandidateFourth;
            entry.CorrectAnswer = form.CorrectAnswer;
            
            dal.SaveChanges();

        }

        public void AddProblem(string courseId, string homeworkId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Include("HomeworkList.Entries").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return;

            List<Homework> homeworkList =
                dal.Homework.Include("Entries").Include("Owner").Where(p => p.Id.ToString() == homeworkId).ToList();
            if (homeworkList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];
            Homework homework = homeworkList[0];

            HomeworkEntry entry = new HomeworkEntry();
            entry.Root = homework;
            entry.Body = "New Problem, Fill Body Here.";
            entry.CandidateFirst = "Candidate A";
            entry.CandidateSecond = "Candidate B";
            entry.CandidateThird = "Candidate C";
            entry.CandidateFourth = "Candidate D";
            entry.CorrectAnswer = "";

            dal.HomeworkEntry.Add(entry);
            homework.Entries.Add(entry);

            dal.SaveChanges();
        }

        public void RemoveProblem(string courseId, string homeworkId, string problemId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Include("HomeworkList.Entries").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return;

            List<Homework> homeworkList =
                dal.Homework.Include("Entries").Include("Owner").Where(p => p.Id.ToString() == homeworkId).ToList();
            if (homeworkList.Count != 1)
                return;

            List<HomeworkEntry> homeworkEntryList =
                dal.HomeworkEntry.Where(p => p.Id.ToString() == problemId).ToList();
            if (homeworkEntryList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];
            Homework homework = homeworkList[0];
            HomeworkEntry entry = homeworkEntryList[0];

            homework.Entries.Remove(entry);
            dal.HomeworkEntry.Remove(entry);

            dal.SaveChanges();
        }

        public UpdateProblemForm FillUpdateProblemForm(string courseId, string homeworkId, string problemId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList = dal.CourseInfo.Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            List<HomeworkEntry> homeworkEntryList = 
                dal.HomeworkEntry.Where(p => p.Id.ToString() == problemId).ToList();
            if (homeworkEntryList.Count != 1)
                return null;
            
            CourseInfo course = courseInfoList[0];
            HomeworkEntry entry = homeworkEntryList[0];

            UpdateProblemForm vm = new UpdateProblemForm();
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();
            vm.HomeworkId = homeworkId;
            vm.ProblemId = problemId;
            vm.Body = entry.Body;
            vm.CandidateFirst = entry.CandidateFirst;
            vm.CandidateSecond = entry.CandidateSecond;
            vm.CandidateThird = entry.CandidateThird;
            vm.CandidateFourth = entry.CandidateFourth;
            vm.CorrectAnswer = entry.CorrectAnswer;

            return vm;
        }

        public AddDiscussForm InitDiscussForm(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("DiscussList.ReplyList").Include("DiscussList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            AddDiscussForm vm = new AddDiscussForm();
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            return vm;
        }

        public ResourceVM GetResourceData(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("ResourceList.Classification").Include("ResourceList.Owner").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];

            ResourceVM vm = new ResourceVM();
            vm.ClassificatedResourceList = new List<ClassificatedResource>();
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            foreach (Resource resource in course.ResourceList)
            {
                List<ClassificatedResource> candidate = vm.ClassificatedResourceList.Where(
                    p => p.Id == resource.Classification.Id.ToString()
                ).ToList();

                string fileSize = (new FileInfo(resource.LocalFilePath).Length / 1024.00).ToString("F2") + " KB";

                if (candidate.Count == 0)
                {
                    ClassificatedResource newClassify = new ClassificatedResource();
                    newClassify.Id = resource.Classification.Id.ToString();
                    newClassify.Caption = resource.Classification.Caption;
                    newClassify.ResourceList = new List<ResourceItem>();
                    newClassify.ResourceList.Add(new ResourceItem
                    {
                        Id = resource.Id.ToString(),
                        Name = resource.Name,
                        Owner = resource.Owner.FullName,
                        UploadDate = resource.UploadDate.ToLongDateString(),
                        DownloadCount = resource.DownloadCount.ToString(),
                        FileType = resource.FileType,
                        FileSize = fileSize
                    });

                    vm.ClassificatedResourceList.Add(newClassify);
                }
                else
                {
                    candidate[0].ResourceList.Add(new ResourceItem
                    {
                        Id = resource.Id.ToString(),
                        Name = resource.Name,
                        Owner = resource.Owner.FullName,
                        UploadDate = resource.UploadDate.ToLongDateString(),
                        DownloadCount = resource.DownloadCount.ToString(),
                        FileType = resource.FileType,
                        FileSize = fileSize
                    });
                }
            }

            return vm;
        }

        public AddResourceForm FillAddResourceForm(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Where(p => p.Id.ToString() == courseId).ToList();

            if (courseInfoList.Count != 1)
                return null;

            AddResourceForm vm = new AddResourceForm();
            CourseInfo course = courseInfoList[0];
            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            List<Classification> classificationList = dal.Classification.ToList();
            vm.ClassList = new List<string>();
            foreach (Classification item in classificationList)
            {
                vm.ClassList.Add(item.Caption);
            }
            return vm;
        }

        public void AddResource(AddResourceForm form, string fileName, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("ResourceList").Where(p => p.Id == form.Id).ToList();

            if (courseInfoList.Count != 1)
                return;

            Resource resource = new Resource();
            resource.Course = courseInfoList[0];
            resource.DownloadCount = 0;
            List<Classification> classificationList = dal.Classification.Where(p => p.Caption == form.Class).ToList();
            if (classificationList.Count == 1)
                resource.Classification = classificationList[0];
            else
            {
                Classification newClass = new Classification();
                newClass.Caption = form.Class;
                dal.Classification.Add(newClass);
                resource.Classification = newClass;
            }
            resource.FileType = form.FileType;
            resource.LocalFilePath = fileName;
            resource.Name = form.Name;
            resource.UploadDate = DateTime.Now;
            resource.Owner = dal.UserInfo.Where(p => p.Username == userName).ToList()[0];

            courseInfoList[0].ResourceList.Add(resource);
            dal.SaveChanges();
        }

        public void RemoveResource(string id, string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<Resource> resourceList = dal.Resource.Where(p => p.Id.ToString() == id).ToList();
            if (resourceList.Count != 1)
                return;

            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("ResourceList").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return;

            courseInfoList[0].ResourceList.Remove(resourceList[0]);
            dal.Resource.Remove(resourceList[0]);
            dal.SaveChanges();
        }

        public string DownloadResource(string id)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<Resource> resourceList = dal.Resource.Where(p => p.Id.ToString() == id).ToList();
            if (resourceList.Count != 1)
                return null;
            resourceList[0].DownloadCount++;
            dal.SaveChanges();
            return resourceList[0].LocalFilePath;
        }

        public AttachedPageArray GetAttachedPageArray(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList.Owner").Where(p => p.Id.ToString() == courseId).ToList();

            if (courseInfoList.Count != 1)
                return null;

            AttachedPageArray attachedPageArray = new AttachedPageArray();
            attachedPageArray.AttachedPageList = new List<AttachedPageItem>();
            List<AttachedPage> pageList = courseInfoList[0].AttachedPageList;

            attachedPageArray.Id = courseInfoList[0].Id;
            attachedPageArray.Title = courseInfoList[0].Title;
            attachedPageArray.StartDate = courseInfoList[0].StartDate.ToLongDateString();
            attachedPageArray.EndDate = courseInfoList[0].EndDate.ToLongDateString();

            foreach (AttachedPage page in pageList)
            {
                AttachedPageItem item = new AttachedPageItem();
                item.Id = page.Id.ToString();
                if (page.Owner != null)
                    item.Owner = page.Owner.FullName;
                item.UpdateTime = page.UpdateTime.ToLongDateString();
                item.ReadCount = page.ReadCount;
                item.Title = page.Title;

                attachedPageArray.AttachedPageList.Add(item);
            }

            return attachedPageArray;
        }

        public void CreateAttachedPage(string courseId, string name)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList").Where(p => p.Id.ToString() == courseId).ToList();

            if (courseInfoList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];

            List<UserInfo> userInfoList = dal.UserInfo.Where(p => p.Username == name).ToList();
            if (userInfoList.Count != 1)
                return;

            AttachedPage newPage = new AttachedPage();
            newPage.Title = "Untitled";
            newPage.Course = course;
            newPage.ReadCount = 0;
            newPage.Owner = userInfoList[0];
            newPage.Content = "Untitled";
            newPage.UpdateTime = DateTime.Now;

            course.AttachedPageList.Add(newPage);
            if (course.DefaultAttachedPage == null)
                course.DefaultAttachedPage = newPage;

            dal.SaveChanges();
        }

        public void RemoveAttachedPage(string id)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList.Owner").Where(p =>
                    p.AttachedPageList.Any(q => q.Id.ToString() == id)).ToList();

            if (courseInfoList.Count != 1)
                return;

            CourseInfo course = courseInfoList[0];
            if (course.DefaultAttachedPage != null && course.DefaultAttachedPage.Id.ToString() == id)
                course.DefaultAttachedPage = null;

            AttachedPage page = courseInfoList[0].AttachedPageList.Where(q => q.Id.ToString() == id).ToList()[0];
            course.AttachedPageList.Remove(page);

            dal.SaveChanges();
        }

        public AttachedPageContentVM GetAttachedPageContent(string id)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList.Owner").Where(p =>
                    p.AttachedPageList.Any(q => q.Id.ToString() == id)).ToList();

            if (courseInfoList.Count != 1)
                return null;

            AttachedPageContentVM vm = new AttachedPageContentVM();
            vm.Id = courseInfoList[0].Id;
            vm.Title = courseInfoList[0].Title;
            vm.StartDate = courseInfoList[0].StartDate.ToLongDateString();
            vm.EndDate = courseInfoList[0].EndDate.ToLongDateString();

            AttachedPage page = courseInfoList[0].AttachedPageList.Where(q => q.Id.ToString() == id).ToList()[0];
            vm.AttachedPageId = id;
            vm.AttachedPageTitle = page.Title;
            vm.Content = page.Content;
            vm.UpdateTime = page.UpdateTime.ToLongDateString();
            page.ReadCount++;
            vm.ReadCount = page.ReadCount;
            if (page.Owner != null)
                vm.Owner = page.Owner.FullName;
            dal.SaveChanges();
            return vm;
        }

        public void UpdateAttachedPage(UpdateAttachedPageForm form, string name)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList").Where(p =>
                    p.AttachedPageList.Any(q => q.Id.ToString() == form.PageId)).ToList();

            if (courseInfoList.Count != 1)
                return;

            List<UserInfo> userInfoList = dal.UserInfo.Where(p => p.Username == name).ToList();
            if (userInfoList.Count != 1)
                return;

            AttachedPage page = courseInfoList[0].AttachedPageList.Where(q => q.Id.ToString() == form.PageId).ToList()[0];
            page.Title = form.PageTitle;
            page.Content = form.Content;
            page.Owner = userInfoList[0];
            page.UpdateTime = DateTime.Now;
            dal.SaveChanges();
        }

        public UpdateAttachedPageForm FillUpdateAttachedPageForm(string id)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("AttachedPageList").Where(p => 
                    p.AttachedPageList.Any(q => q.Id.ToString() == id)).ToList();

            if (courseInfoList.Count != 1)
                return null;

            UpdateAttachedPageForm form = new UpdateAttachedPageForm();
            form.Id = courseInfoList[0].Id;
            form.Title = courseInfoList[0].Title;
            form.StartDate = courseInfoList[0].StartDate.ToLongDateString();
            form.EndDate = courseInfoList[0].EndDate.ToLongDateString();

            AttachedPage page = courseInfoList[0].AttachedPageList.Where(q => q.Id.ToString() == id).ToList()[0];
            form.PageId = id;
            form.PageTitle = page.Title;
            form.Content = page.Content;

            return form;
        }

        public UpdateOverviewForm GetCoursePartialOverview(string courseId, string section)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id.ToString() == courseId).ToList();

            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            UpdateOverviewForm item = new UpdateOverviewForm();
            item.Id = course.Id;
            item.Title = course.Title;
            item.StartDate = course.StartDate.ToLongDateString();
            item.EndDate = course.EndDate.ToLongDateString();
            // Teacher not filled
            item.SectionName = section;
            switch (section)
            {
                case "Description":
                    item.Content = course.Description;
                    break;
                case "Prerequisites":
                    item.Content = course.Prerequisites;
                    break;
                case "Textbook":
                    item.Content = course.Textbook;
                    break;
                case "ScoringRule":
                    item.Content = course.ScoringRule;
                    break;
                default:
                    return null;
            }
            return item;
        }

        public CourseOverview GetCourseOverview(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id.ToString() == courseId).ToList();

            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            CourseOverview item = new CourseOverview();
            item.Id = course.Id;
            item.Title = course.Title;
            item.Description = course.Description;
            item.StartDate = course.StartDate.ToLongDateString();
            item.EndDate = course.EndDate.ToLongDateString();
            List<UserInfo> teachers =
                course.FollowedUserList.Where(p => p.Privilege == UserPrivilege.Teacher).ToList();

            item.InvolvedTeachers = new List<TeacherShortItem>();
            foreach (UserInfo user in teachers)
            {
                TeacherShortItem newEntry = new TeacherShortItem();
                newEntry.FullName = user.FullName;
                newEntry.ProfTitle = user.ProfTitle;
                newEntry.Website = user.Website;
                newEntry.Email = user.Email;
                item.InvolvedTeachers.Add(newEntry);
            }

            item.Prerequisites = course.Prerequisites;
            item.Textbook = course.Textbook;
            item.ScoringRule = course.ScoringRule;
            return item;
        }

        public void InsertCourseInfo(CourseBasicInfoForm register)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            CourseInfo newEntry = new CourseInfo();
            newEntry.Title = register.CourseTitle;
            newEntry.StartDate = register.StartTime;
            newEntry.EndDate = register.EndTime;
            dal.CourseInfo.Add(newEntry);
            dal.SaveChanges();
        }

        public CourseBasicInfoForm GetCourseInfo(string courseId)
        {
            TinyMoocDAL dal = new TinyMoocDAL();            
            List<CourseInfo> courseInfoList = 
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count == 1)
            {
                CourseBasicInfoForm bvm = new CourseBasicInfoForm();
                CourseInfo course = courseInfoList[0];
                bvm.CourseId = course.Id;
                bvm.CourseTitle = course.Title;
                bvm.StartTime = course.StartDate;
                bvm.EndTime = course.EndDate;
                bvm.TeacherList = new List<TeacherSelection>();
                List<UserInfo> teachers = dal.UserInfo.Where(p => p.Privilege == UserPrivilege.Teacher).ToList();
                foreach (UserInfo item in teachers)
                {
                    TeacherSelection entry = new TeacherSelection();
                    entry.FullName = item.FullName;
                    entry.Selected = course.FollowedUserList.Exists(p => p.FullName == item.FullName);

                    bvm.TeacherList.Add(entry);
                }
                return bvm;
            }
            return null;
        }

        public void UpdateCourseInfo(CourseBasicInfoForm register, string[] teachers)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList = 
                dal.CourseInfo.Include("FollowedUserList").Where(p => p.Id == register.CourseId).ToList();
            if (courseInfoList.Count == 1)
            {
                CourseInfo newEntry = courseInfoList[0];
                newEntry.Title = register.CourseTitle;
                newEntry.StartDate = register.StartTime;
                newEntry.EndDate = register.EndTime;

                newEntry.FollowedUserList.RemoveAll(p => p.Privilege == UserPrivilege.Teacher);
                foreach (string item in teachers)
                {
                    List<UserInfo> user = dal.UserInfo.Where(p => p.FullName == item).ToList();
                    if (user.Count == 1)
                    {
                        newEntry.FollowedUserList.Add(user[0]);
                    }
                }
            }

            dal.SaveChanges();
        }


        public void AddHomework(AddHomeworkForm form, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Include("HomeworkList.Owner").Where(p => p.Id == form.Id).ToList();
            if (courseInfoList.Count != 1)
                return;

            Homework newHomework = new Homework();

            newHomework.Title = form.HomeworkTitle;
            newHomework.StartDate = form.HomeworkStartDate;
            newHomework.EndDate = form.HomeworkEndDate;
            newHomework.Course = courseInfoList[0];
            newHomework.Entries = new List<HomeworkEntry>();
            newHomework.Owner = dal.UserInfo.Where(p => p.Username == userName).ToList()[0];
            courseInfoList[0].HomeworkList.Add(newHomework);

            dal.SaveChanges();
        }

        public void AlterHomework(AddHomeworkForm form, string userName)
        {
            TinyMoocDAL dal = new TinyMoocDAL();
            List<Homework> homeworkList = dal.Homework.Where(p => p.Id.ToString() == form.HomeworkId).ToList();
            if (homeworkList.Count != 1)
                return;

            Homework homework = homeworkList[0];

            homework.Title = form.HomeworkTitle;
            homework.StartDate = form.HomeworkStartDate;
            homework.EndDate = form.HomeworkEndDate;
            dal.SaveChanges();
        }

        public AddHomeworkForm InitHomeworkForm(string courseId, string homeworkId = null)
        {
            TinyMoocDAL dal = new TinyMoocDAL();

            List<CourseInfo> courseInfoList =
                dal.CourseInfo.Where(p => p.Id.ToString() == courseId).ToList();
            if (courseInfoList.Count != 1)
                return null;

            CourseInfo course = courseInfoList[0];
            AddHomeworkForm vm = new AddHomeworkForm();

            vm.Id = course.Id;
            vm.Title = course.Title;
            vm.StartDate = course.StartDate.ToLongDateString();
            vm.EndDate = course.EndDate.ToLongDateString();

            if (homeworkId == null)
                return vm;

            List<Homework> homeworkList = dal.Homework.Where(p => p.Id.ToString() == homeworkId).ToList();
            if (homeworkList.Count != 1)
                return null;

            Homework homework = homeworkList[0];

            vm.HomeworkId = homeworkId;
            vm.HomeworkTitle = homework.Title;
            vm.HomeworkStartDate = homework.StartDate;
            vm.HomeworkStartDate = homework.EndDate;
            return vm;
        }
    }
}
